%{
  #include<stdio.h>
  #include "syntax_tree.h"
  #include "symbol_table.h"
  #include"interpreter.h"

  int yylex(void);
  void yyerror(char*);
  symbol_table st=NULL;
  extern FILE* yyin;
%}
%union{
	char * istring;
	int iValue;
	struct syntax_table * stValue;
	//	syntax_t stValue;
};
%token <iValue> INT
%token <istring> ID
%token IF ELSE
%token PRINT
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS

%type <iValue> expr
%type <stValue> statement selection_statement statement_block var

%%
program:
      statement_list {return 0;}
    ;
statement_list:
    | statement_list statement { itpt_ret_free(interpreter($2));}
    |
    ;

statement :
      ID '=' expr ';'          { $$=syntax_t_new('=',2,syntax_t_id($1),syntax_t_const($3)); }
    | selection_statement      {$$=$1;}
    | '{' statement_block '}'  {$$=$2;}
    | PRINT '(' var ')' ';'    { $$=syntax_t_new(PRINT,1,$3);}
    | ';' { $$=syntax_t_new(';',2,NULL,NULL);}
    ;

selection_statement:
      IF '(' var ')' statement ELSE statement {$$=syntax_t_new(IF,3,$3,$5,$7);}
    | IF '(' var ')' statement  {$$=syntax_t_new(IF,2,$3,$5);}
    ;

statement_block:
      statement      {$$=$1;}
    | statement_block statement {$$=syntax_t_new(';',2,$1,$2);}
    ;

var :
      ID                { $$ = syntax_t_id($1); }
    | INT               { $$ = syntax_t_const($1); }
    ;

expr:
      INT                { $$ = $1;}
    | expr '+' expr      { $$= $1 + $3; }
    | expr '-' expr      { $$ =$1 - $3; }
    | expr '/' expr      { 
				if($3==0)
					yyerror("div by zero!\n");
				else
					$$ =$1 / $3; }
    | expr '*' expr      { $$ =$1 * $3; }
    | '-' expr  %prec UMINUS { $$ =-$2; }
    | '(' expr ')'       { $$= $2;      }
    ;
%%
void yyerror(char *s){
  fprintf(stderr,"%s\n",s);
}

int main(int argc, char *argv[])
{
	int i=0;
	st=symbol_table_init();
	if(argc >= 2)
		{
			for (i = 1; i < argc; ++i)
				{
					if((yyin=fopen(argv[i],"r"))==NULL)
						continue;
					yyparse();
					fclose(yyin);
				}
		}
	else{
		yyparse();
	}
    return 0;
}
